package loadBalancer;

import cn.hutool.core.collection.CollUtil;
import model.ServiceInfo;

import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * 一致性哈希算法负载均衡器
 */
public class ConsistentHashBalancer implements LoadBalance {
    /**
     * 用TreeMap模拟一致性哈希环
     */
    private static final TreeMap<Integer, ServiceInfo> hashRound = new TreeMap<>();
    /**
     * 虚拟节点个数，默认每个服务有10个
     */
    private static final Integer VIRTUAL_NODES = 10;

    public ServiceInfo selectServiceFromList(Map<String, Object> requestParams, List<ServiceInfo> serviceInfoList) {
        // 为空则返回null，说明没有可用服务
        if (CollUtil.isEmpty(serviceInfoList))
            return null;
        // 动态构建哈希环
        for (ServiceInfo serviceInfo : serviceInfoList) {
            for (int i = 0; i < VIRTUAL_NODES; i++) {
                int hashValue = getHash(serviceInfo.getServiceNodeKey() + "@" + i);
                hashRound.put(hashValue, serviceInfo);
            }
        }
        int targetHashValue = getHash(requestParams);
        // 取顺时针方向最接近targetHashValue的节点
        Map.Entry<Integer, ServiceInfo> selectedServiceInfo = hashRound.ceilingEntry(targetHashValue);
        // 没有则返回环首个节点
        if (selectedServiceInfo == null)
            return hashRound.firstEntry().getValue();
        return selectedServiceInfo.getValue();

    }

    /**
     * 自定义哈希函数值
     */
    Integer getHash(Object object) {
        return object.hashCode();
    }
}
